import React from 'react'
import './index.css'
import { Toast } from 'antd-mobile'
import NavHeader from '../../components/NavHeader'
import request from '../../utils/request'
import getCurrentCity from '../../utils/currentCity' // 获取当前默认城市方法，方法内部从本地读取，读不到就调用百度api获取，最后返回一个promise
import { List , AutoSizer  } from 'react-virtualized' // 可是区域渲染插件
import axios from 'axios'
 
// 定义标题高度和List每一行高度
const TITLE_HEUGHT = 36
const NAME_HEIGHT = 50

export default class CityList extends React.Component {
  constructor (props) {
    super(props)
    this.state = {
      cityIndex: [],
      cityList: {},
      active: 0 // 决定右侧的索引号是否高亮
    }
    this.compoentRef = React.createRef() // 新建ref对象方法，谁要帮你打那个就把这个放到ref属性中
  }
  // 钩子函数,首次渲染触发
  async componentDidMount () {
    await this.getCityList() // 获取城市数据
    // await 等于gannert 里面的 yaid
    // 调用组件ref身上的函数
    this.compoentRef.current.measureAllRows()
  }
  async fromatCityData (data, hot) { // 整理返回的数据,保存到state状态中
    // 将返回的 全国城市名字整理成两个数据。
    // 一个是对象，键值对是 字母对应首字母开头
    // 一个是a-z
    // 最后又加上了默认城市（当前）和hot城市
    var cityIndex = []
    var cityList = {}
    // 生成a-z
    // for(var i = 65; i < 91; i++){
    //   cityIndex.push(String.fromCharCode(i))
    // }
    data.forEach(item => {
      const first = item.pinyin.slice(0,1)
      if ( cityList[first]) { // 如果已经加过了，push
        cityList[first].push(item)
      } else { // 第一次来，新建
        cityList[first] = [item]
        cityIndex.push(first)
      }
    })
    // abc排序
    cityIndex.sort()
    // 添加热门数据到数组中
    cityList['hot'] = hot
    cityIndex.unshift('hot')
    // key 方法 只获取对象的属性名
    // let cityIndex = Object.keys(cityList).sort()
    let currentCity = await getCurrentCity()
    cityList['#'] = [currentCity] // 属性#的值为 currentCity，它是一个对象
    cityIndex.unshift('#')
    this.setState(_ => {
      return {
        cityIndex,
        cityList
      }
    })
  }
  async getCityList () { // 获取城市数据
    const { data: res } = await axios.get('http://api-haoke-web.itheima.net/area/city?level=1')
    const { data: ress } = await request('/area/hot', 'GET')
    this.fromatCityData(res.body, ress.body)  
  }
  
  fromatCityIndex (city) { // 将CityIndex中的小写转化为大写
    switch (city) {
      case '#':
      return '当前定位'
      case 'hot':
      return '热门城市'
      default :
        return city.toUpperCase()
    }
  }
   changeCity = async (city) => { // 点击切换城市
    const { data: res } = await request(`/area/info?name=${city.label}`,'GET')
    const Newcity = res.body
    if (city.label !== '上海' && Newcity.label === '上海') return Toast.info('当前城市没有房源', 1, null, false)
    // 有数据，存到本地
    localStorage.setItem('city', JSON.stringify({
      label: city.label,
      value: city.value
  }))
    // this.props.history.push('/home/index')
    this.props.history.go(-1)
  } 
  rowRenderer = ({ // react-virtualized组件渲染list方法
    key,         // Unique key within array of rows
    index,       // 索引号
    isScrolling, // 当前项是否正在滚动中
    isVisible,   // 当前项在List中是可见的
    style        // 重点属性：一定要给每一个行数添加该样式，将下方的list组件传的属性接收了
  }) => {
    const city = this.state.cityIndex[index]
    return (
      <div
        key={key}
        style={style}
      >
        {/* 内部会循环遍历生成的 */}
        <div className='title'>
          {this.fromatCityIndex(city)}
        </div>
        <div className='name' >
          {this.state.cityList[city].map(item => {
          return <div key={item.value} onClick={_ => this.changeCity(item)}>{item.label}</div>
        })}
        </div>
      </div>
    )
  }
  getHeight = ({ index }) => { // 计算List每一项的高度
    let { cityIndex, cityList } = this.state
    return TITLE_HEUGHT + NAME_HEIGHT * cityList[cityIndex[index]].length
  }
  changeIndex = (index) => { // 点击右侧li按钮切换索引城市
    // 调用List组件自带的方法scrollToRow，可以进行页面跳转
    // 这个方法在下方list未渲染过的时候会出现误差,使用组件的measureAllRows 方法，可以计算出下面list项目的高度
    // 由于我们已经写了页面滚动到list就改变active的方法，此时就不用再改变active
    this.setState(_ => {
      return {
        active: index
      }
    })
    // 让索引号高亮了之后，开始让页面滚动到响应的位置
    this.compoentRef.current.scrollToRow(index)
  }
  renderRightIndex () { // 渲染右侧的索引列表
    const { cityIndex } = this.state
    return cityIndex.map((item, index) => {
      return (
            <li className='city-index-item' key={index} onClick={_ => this.changeIndex(index)}>
              <span className={this.state.active === index ? 'index-active' : ''} >{item === '#' ? '#' :this.fromatCityIndex(item).slice(0,1)}</span>
            </li>
            )
    })
  }
  onRowsRendered = ({ startIndex }) => { // 组件自带的函数，用于获取当前展示的项目索引
    // 结构赋值出startIndex，为当前上方展示的list中最后一个item的索引
    if (this.state.active !== startIndex) { // 判断是不是还是处于上一个list 的item的索引号,避免不必要的更新
      this.setState(_ => {
        return {
          active: startIndex
        }
      })
    }
  }
  render() {
    return (
      <div className='cityList'>
        <div className='navBar'>
          <NavHeader>城市选择</NavHeader>
        </div>
          {/* 列表 */}
          {/* 使用AutoSizer 组件可以获取当前可用宽度和高度 */}
          <AutoSizer>
            {({height, width}) => ( <List
            ref={this.compoentRef}
            // 组件的宽度
            width={width}
            // 组件的高度
            height={height}
            rowCount={this.state.cityIndex.length}
            // 每行的高度
            rowHeight={this.getHeight}
            rowRenderer={this.rowRenderer}
            onRowsRendered={this.onRowsRendered}
            scrollToAlignment='start'
            // scrollToAlignment='start' 设置每次点击滑动后都会显示最开始的List
          />)}
          </AutoSizer>
          {/* 右侧索引 */}
          <ul className='city-index'>
            {/* 函数没有注册事件，不用担心this */}
            {this.renderRightIndex()}
          </ul>
      </div>
    )
  }
}